package nl.science.uva.pico.operator;

import nl.science.uva.pico.ProgramCounter;
import nl.science.uva.pico.Stack;
import nl.science.uva.pico.operand.Operand;
import nl.uva.science.pico.stacklanguage.types.LabelInstrList;

/** 
 * IfEqual compares 2 integer values 
 * 
 * @author Ivo van Dongen, Karel Pieterson
 * @version 1.0  
 */
public class IfEqual extends Operator {

	public IfEqual(Stack stack, ProgramCounter programCounter,LabelInstrList programListing) {
		super(stack, programCounter, programListing);
	}

    /** 
     * ifeq This instruction checks whether the top most two elements of the stack are equal. 
     * Equality check applies either to two integer constants or to two string constants. 
     * When both elements are equal, execution of the program is continued at statement labeled x, 
     * otherwise the next statement is executed.
     *  
     *  @throws IllegalStateException
     */
	@Override
	public void perform() {
		Operand[] operands = new Operand[2];
		
		if(getStack().size() >= 3) {
			operands[0] = getStack().pop();
			operands[1] = getStack().pop();

			Integer label = getStack().pop().getIntegerValue();
			
			boolean equals = false;
			if(operands[0].isStringConstant() && operands[1].isStringConstant()) {
				equals = operands[0].getStringValue().equals(operands[1].getStringValue());
			} else if(operands[0].isIntegerConstant() && operands[1].isIntegerConstant()) {
				equals = operands[0].getIntegerValue().equals(operands[1].getIntegerValue());
			} else {
				throw new IllegalStateException("IfEqual can only compare similar types");
			}
			
			if(equals) {
				gotoLabel(label);
			}
		} else {
			throw new IllegalStateException(" Too few operands, IfEqual needs 2 operands");
		}
		
	}

}
